package com.apes.scm.stock.transfer.model;

import com.apes.framework.api.SpringManager;
import com.apes.framework.jpa.BaseModel;
import com.apes.framework.jpa.DefaultPersistListener;
import com.apes.framework.jpa.generator.ApesGenerator;
import com.apes.framework.util.ApesConst;
import com.apes.scm.masterdata.product.model.Product;
import com.apes.scm.masterdata.product.model.ProductUom;
import com.apes.scm.masterdata.product.service.UomService;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.SelectBeforeUpdate;

import javax.persistence.*;
import javax.validation.constraints.NotNull;

/**
 * 功能：仓库作业明细（拣配、调拨）
 *
 * @author xul
 * @create 2018-01-31 14:21
 */

@Getter
@Setter
@SelectBeforeUpdate
@DynamicInsert
@DynamicUpdate
@Entity
@EntityListeners(DefaultPersistListener.class)
@Table(name = PickItem.CONST_TABLE_NAME)
public class PickItem extends BaseModel {
    public static final String CONST_TABLE_NAME = "stock_pick_item";

    @Id
    @Column(name = "id")
    @ApesGenerator(code = CONST_TABLE_NAME, name = "交货单明细行")
    private long id;

    @NotNull
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "product_id", referencedColumnName = "id")
    private Product product; //商品

    @Column(name = "product_uom_qty", nullable = false, columnDefinition = ApesConst.FIELD_16_4_0)
    private double productUomQty = 0; //待办数量

    public void setProductUomQty(double productUomQty) {
        if (productUomQty < 0) {
            throw new RuntimeException("待办数量不允许为负数");
        }
        this.productUomQty = productUomQty;
    }

    @Column(name = "qty_done", nullable = false, columnDefinition = ApesConst.FIELD_16_4_0)
    private double qtyDone = 0; //完成数量

    public void setQtyDone(double qtyDone) {
        if (qtyDone < 0) {
            throw new RuntimeException("完成数量不允许为负数");
        }
        this.qtyDone = qtyDone;
    }

    @Column(name = "ordered_qty", nullable = false, columnDefinition = ApesConst.FIELD_16_4_0)
    private double orderedQty = 0; //订购数量

    public void setOrderedQty(double orderedQty) {
        if (orderedQty < 0) {
            throw new RuntimeException("订购数量不允许为负数");
        }
        this.orderedQty = orderedQty;
    }

    @Column(name = "frost_qty",  nullable = false, columnDefinition = ApesConst.FIELD_QTY_16_4_0)
    private double frostQty = 0.0;  //冻结数量

    public void frost(double incurred){
        frostQty += incurred;
        if (frostQty < 0) {
            throw new RuntimeException("冻结数量不允许为负数");
        }
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "product_uom_id", referencedColumnName = "id")
    private ProductUom uom; //计量单位

    @NotNull
    @ManyToOne(optional = false)
    @JoinColumn(name = "pick_id", referencedColumnName = "id")
    private Pick pick;

    @Column(name = "origin_line")
    private String originLine;  //来源行号

    @Transient
    private double factor;

    public double getFactor() {
        if (uom != null) return 1/uom.getFactor();
        return 0;
    }

    /**
     * 交货
     */
    public void delivery(double qtyDone) {
        this.qtyDone += qtyDone;
        if (this.qtyDone > this.productUomQty - this.frostQty) {
            throw new RuntimeException("交货数量不允许大于待交货数量！");
        }
        if (this.getPick().getMoveType().getId().equals("one") && this.qtyDone != this.productUomQty) {
            throw new RuntimeException("交货数量必须等于待交货数量！");
        }
    }

    public void cancle(double qtyDone){
        this.qtyDone += qtyDone;
        if (this.qtyDone > this.productUomQty - this.frostQty) {
            throw new RuntimeException("交货数量不允许大于待交货数量！");
        }
    }

    /*
     * 功能：计算基本单位完成数量
     */
    public double computeQtyUnit() {
        ProductUom baseUom = getProductUom();
        if (this.getUom().getId() != baseUom.getId()) {
            return this.getUom().computeQty(this.qtyDone, baseUom, true);
        }
        return this.qtyDone;
    }

    private ProductUom getProductUom() {
        return SpringManager.getBean(UomService.class).getUom(this.getPick().getCompany(), this.getProduct());
    }

}
